﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MQTTnet;
using Transponder_Core.DataTarget;

namespace Transponder_Core.DataSource
{
    public class MqttSource
    {

        public IMqttClient mMqttClient;

        public string Host { get; set; } = "121.196.236.225";
        public int Port { get; set; } = 12010;

        public string UserName { get; set; } = "admin";

        public string Password { get; set; } = "Admin,123456";
        public string ClientId { get; set; }  = Guid.NewGuid().ToString();

        /// <summary>
        /// 
        /// </summary>
        public string EventReportTopic { get; set; } = "ztnjbz/eventReport/#";

        /// <summary>
        /// 
        /// </summary>
        public string RealTimeElectricalParametersTopic { get; set; } = "ztnjbz/RealTimeElectricalParameters";
        public MqttSource()
        {
                
        }


        /// <summary>
        /// 
        /// </summary>
        public async Task  Open()
        {
            IsConnected = true;

            var factory = new MqttClientFactory();

            // 通过工厂创建MQTT客户端
            mMqttClient = factory.CreateMqttClient();

            // 使用建造者模式创建MQTT客户端连接选项
            var options = new MqttClientOptionsBuilder()
               .WithTcpServer(Host, Port)  // 设置MQTT服务器地址和端口
               .WithClientId(ClientId)
               .WithCredentials(UserName, Password)
               .WithCleanSession()                // 启用清洁会话（不保留历史会话状态）
               .Build();                          // 构建配置选项对象


            mMqttClient.ConnectedAsync += MMqttClientSource_ConnectedAsync;

            mMqttClient.DisconnectedAsync += MMqttClientSource_DisconnectedAsync;

            mMqttClient.ApplicationMessageReceivedAsync += MMqttClientSource_ApplicationMessageReceivedAsync;
             
            await mMqttClient.ConnectAsync(options);

        }

        /// <summary>
        /// 
        /// </summary>
        public bool IsConnected { get; private set; }



        public event EventHandler<EventReportEventArgs> EventReportReceived;

        /// <summary>
        /// 
        /// </summary>
        public event EventHandler<RealTimeElectricalParametersEventArgs> RealTimeElectricalParametersReceived;

        /// <summary>
        /// 
        /// </summary>
        public event EventHandler<EventArgs> Disconnected;

        /// <summary>
        /// 
        /// </summary>
        public event EventHandler<EventArgs> Connected;
         
        /// <summary>
        /// 
        /// </summary>
        /// <param name="arg"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private async Task MMqttClientSource_ApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs arg)
        {
            if (arg.ApplicationMessage.Topic.StartsWith("ztnjbz/eventReport"))
            {
                
                var sourceObj = EventReport.FromJson(arg.ApplicationMessage.ConvertPayloadToString());

                if (sourceObj != null) { 
                
                    this.EventReportReceived?.Invoke(this,new EventReportEventArgs(sourceObj));
                }

            }
            else if (arg.ApplicationMessage.Topic.StartsWith("ztnjbz/RealTimeElectricalParameters"))
            {
                
                var sourceObj = RealTimeElectricalParameters.FromJson(arg.ApplicationMessage.ConvertPayloadToString());

                if (sourceObj != null)
                {

                    this.RealTimeElectricalParametersReceived?.Invoke(this, new RealTimeElectricalParametersEventArgs(sourceObj));
                }
            }
          await  Task.Delay(0);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public async Task DisconnectAsync()
        {
            await mMqttClient.DisconnectAsync();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="arg"></param>
        /// <returns></returns>
        private async Task MMqttClientSource_DisconnectedAsync(MqttClientDisconnectedEventArgs arg)
        {
            Disconnected?.Invoke(this, new EventArgs());
            await Task.Delay(1000);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="arg"></param>
        /// <returns></returns>
        private async Task MMqttClientSource_ConnectedAsync(MqttClientConnectedEventArgs arg)
        {
            this.Connected?.Invoke(this, new EventArgs());
             
            if (!string.IsNullOrWhiteSpace(EventReportTopic))
            {
                await mMqttClient.SubscribeAsync(EventReportTopic);
            }
            if (!string.IsNullOrWhiteSpace(RealTimeElectricalParametersTopic))
            {
                await mMqttClient.SubscribeAsync(RealTimeElectricalParametersTopic);
            }

           
        }
    }
}
